﻿using System;

using System.Collections.Generic;
using System.Text;
using Silvermoon.Visuals;
using System.Drawing;
using Silvermoon.Controls.Classes;
using Silvermoon.Controls.Interfaces;
using Silvermoon.Utils;
using Silvermoon.Images;
using Silvermoon.Controls.Base;

namespace Silvermoon.Controls
{
    /// <summary>
    /// Container Control to be used within a <see cref="T:ListView"/>.
    /// </summary>
    public class ListViewItem : ItemBase, ICompositeControl, IMouseEventBehavior, ISelectable
    {
        #region const

        #endregion
        #region fields

        internal ListViewItemAnimation animation;
        private BackgroundVisual background;
        private RectangleVisual borderLine;
        private List<Visual> visuals = new List<Visual>(2);

        #endregion
        #region ctor

        public ListViewItem()
            : base()
        {
            this.Controls = new List<Control>();
            ShowBorderLine = true;
            Visuals = visuals;
        }

        public override void Dispose()
        {
            if (background != null) background.Dispose();
            if (borderLine != null) borderLine.Dispose();
            background = null;
            borderLine = null;
            Visuals = null;

            if (animation != null)
            {
                animation.Abort();
                animation = null;
            }
            base.Dispose();
        }

        #endregion
        #region Props

        /// <summary>
        /// Gets or sets whether to show the border line.
        /// </summary>
        public bool ShowBorderLine { get; set; }

        /// <summary>
        /// Gets the actual height that depends on the current animation. If no animation is in progress, this value is equal to Height.
        /// </summary>
        public override int ActualHeight
        {
            get { return animation == null ? Height : animation.ActualHeight; }
        }

        public override Rectangle ActualBounds
        {
            get
            {
                if (animation == null) return base.ActualBounds;
                return new Rectangle(X, Y, Width, ActualHeight);
            }
            set { base.ActualBounds = value; }
        }

        #endregion
        #region Methods


        private void InitBorderLine()
        {
            if (borderLine != null)
            {
                borderLine.Bounds = new Rectangle(0, ScaleY(Height) - 1, ScaleX(Width), 1);
            }
        }

        private void InitBackground()
        {
            if (background != null) background.Bounds = Control.Scale(ClientBounds);
        }

        protected override void OnLayout()
        {
            if (CheckFlag(InvalidationFlag.LayoutAppearance | InvalidationFlag.Size | InvalidationFlag.Color | InvalidationFlag.TextColor))
            {
                if (IsSelected)
                {
                    if (background == null)
                    {
                        background = new BackgroundVisual { Colors = ColorUtil.CreateFlatChromeColors(SysColors.HighlightedItemColor), Style = RenderStyle.Chrome };
                        background.Texture = SysImages.ItemBackground;
                        InitBackground();
                    }
                    if (!visuals.Contains(background)) visuals.Add(background);
                }
                else
                {
                    if (background != null) visuals.Remove(background);
                }

                if (ShowBorderLine)
                {
                    if (borderLine == null)
                    {
                        borderLine = new RectangleVisual { Color = SysColors.ItemBorderLineColor };
                        InitBorderLine();
                    }
                    if (!visuals.Contains(borderLine)) visuals.Add(borderLine);
                }
                else
                {
                    if (borderLine != null)
                    {
                        visuals.Remove(borderLine);
                        borderLine.Dispose();
                    }
                    borderLine = null;
                }
                InitBackground();
                InitBorderLine();
            }

            base.OnLayout();
        }


        public override void OnSelectedChanged()
        {
            base.OnSelectedChanged();
            TextColor = IsSelected ? SysColors.HighlightedItemTextColor : SysColors.ListViewTextColor;
            Invalidate(InvalidationFlag.LayoutAppearance);
        }

        public bool CanAnimate
        {
            get
            {
                ListViewBase lv = this.ListView;
                return !lv.IsInitializing && lv.Created && lv.Visible;
            }
        }

        public override void Removing()
        {
            if (CanAnimate)
            {
                animation = new ListViewItemAnimation(this);
                animation.PerformRemove();
            }
        }

        public override void Inserting()
        {
            if (CanAnimate)
            {
                animation = new ListViewItemAnimation(this);
                animation.PerformInsert();
            }
        }

        #endregion
        #region ICompositeControl Members

        public IList<Control> Controls
        {
            get;
            private set;
        }

        protected internal override IList<Control> SubControls
        {
            get { return Controls; }
        }

        #endregion

    }
}
